home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / raid / devRaidUtil.c < prev    next >
C/C++ Source or Header  |  1990-11-09  |  17KB  |  669 lines

  1. /* 
  2.  * devRaidUtil.c --
  3.  *
  4.  *    Routines for allocating, initializing and deallocating various
  5.  *    RAID data structures.
  6.  *    Routines for mapping logical RAID sectors to physical devices.
  7.  *
  8.  * Copyright 1989 Regents of the University of California
  9.  * All rights reserved.
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose and without
  12.  * fee is hereby granted, provided that the above copyright
  13.  * notice appear in all copies.  The University of California
  14.  * makes no representations about the suitability of this
  15.  * software for any purpose.  It is provided "as is" without
  16.  * express or implied warranty.
  17.  */
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: /sprite/src/kernel/raid/RCS/devRaidUtil.c,v 1.13 90/11/09 13:15:52 eklee Exp $ SPRITE (Berkeley)";
  21. #endif /* not lint */
  22.  
  23. #include "sync.h"
  24. #include "sprite.h"
  25. #include "fs.h"
  26. #include "dev.h"
  27. #include "devBlockDevice.h"
  28. #include "devRaid.h"
  29. #include "semaphore.h"
  30. #include "stdlib.h"
  31. #include "dbg.h"
  32. #include "devRaidUtil.h"
  33. #include "devRaidProto.h"
  34.  
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * InitRaidBlockRequest --
  40.  *
  41.  *    Initialize RaidBlockRequest.
  42.  *
  43.  * Results:
  44.  *    None.
  45.  *
  46.  * Side effects:
  47.  *    None.
  48.  *
  49.  *----------------------------------------------------------------------
  50.  */
  51.  
  52. static void
  53. InitRaidBlockRequest(reqPtr, raidPtr, operation, col, row, diskSector,
  54.     numSectorsToTransfer, buffer, ctrlData)
  55.     RaidBlockRequest    *reqPtr;
  56.     Raid        *raidPtr;
  57.     int             operation;
  58.     int             col, row;
  59.     unsigned         diskSector;
  60.     int             numSectorsToTransfer;
  61.     Address         buffer;
  62.     int             ctrlData;
  63. {
  64.     reqPtr->devReq.operation     = operation;
  65.     reqPtr->devReq.startAddress  = SectorToByte(raidPtr, diskSector);
  66.     reqPtr->devReq.startAddrHigh = 0;
  67.     reqPtr->devReq.bufferLen     = SectorToByte(raidPtr, numSectorsToTransfer);
  68.     reqPtr->devReq.buffer        = buffer;
  69.     reqPtr->devReq.ctrlData[0]   = ctrlData;
  70.     reqPtr->state                = REQ_READY;
  71.     reqPtr->status               = FAILURE;
  72.     reqPtr->raidPtr              = raidPtr;
  73.     reqPtr->col                  = col;
  74.     reqPtr->row                  = row;
  75.     reqPtr->diskPtr              = raidPtr->disk[col][row];
  76.     reqPtr->version              = reqPtr->diskPtr->version;
  77. }
  78.  
  79.  
  80. /*
  81.  *----------------------------------------------------------------------
  82.  *
  83.  * Raid_MakeBlockDeviceRequest --
  84.  *
  85.  *    Allocate and initialize DevBlockDeviceRequest.
  86.  *
  87.  * Results:
  88.  *    None.
  89.  *
  90.  * Side effects:
  91.  *    None.
  92.  *
  93.  *----------------------------------------------------------------------
  94.  */
  95.  
  96. DevBlockDeviceRequest *
  97. Raid_MakeBlockDeviceRequest(raidPtr, operation, diskSector, numSectorsToTransfer,
  98.     buffer, doneProc, clientData, ctrlData)
  99.     Raid        *raidPtr;
  100.     int             operation;
  101.     unsigned         diskSector;
  102.     int             numSectorsToTransfer;
  103.     Address         buffer;
  104.     void           (*doneProc)();
  105.     ClientData         clientData;
  106.     int             ctrlData;
  107. {
  108.     DevBlockDeviceRequest    *requestPtr =
  109.     (DevBlockDeviceRequest *) Malloc(sizeof(DevBlockDeviceRequest));
  110.  
  111.     requestPtr->operation     = operation;
  112.     requestPtr->startAddress  = SectorToByte(raidPtr, diskSector);
  113.     requestPtr->startAddrHigh = 0;
  114.     requestPtr->bufferLen     = SectorToByte(raidPtr, numSectorsToTransfer);
  115.     requestPtr->buffer        = buffer;
  116.     requestPtr->doneProc      = doneProc;
  117.     requestPtr->clientData    = clientData;
  118.     requestPtr->ctrlData[0]   = ctrlData;
  119.  
  120.     return requestPtr;
  121. }
  122.  
  123.  
  124. /*
  125.  *----------------------------------------------------------------------
  126.  *
  127.  * Raid_FreeBlockDeviceRequest --
  128.  *
  129.  *    Free DevBlockDeviceRequest.
  130.  *
  131.  * Results:
  132.  *    None.
  133.  *
  134.  * Side effects:
  135.  *    None.
  136.  *
  137.  *----------------------------------------------------------------------
  138.  */
  139.  
  140. void
  141. Raid_FreeBlockDeviceRequest(requestPtr)
  142.     DevBlockDeviceRequest    *requestPtr;
  143. {
  144.     Free((char *) requestPtr);
  145. }
  146.  
  147.  
  148. /*
  149.  *----------------------------------------------------------------------
  150.  *
  151.  * MakeRaidIOControl --
  152.  *
  153.  *    Allocate and initialize RaidIOControl.
  154.  *
  155.  * Results:
  156.  *    None.
  157.  *
  158.  * Side effects:
  159.  *    None.
  160.  *
  161.  *----------------------------------------------------------------------
  162.  */
  163.  
  164. RaidIOControl *
  165. Raid_MakeIOControl(doneProc, clientData)
  166.     void           (*doneProc)();
  167.     ClientData         clientData;
  168. {
  169.     RaidIOControl    *IOControlPtr;
  170.     IOControlPtr = (RaidIOControl *) Malloc(sizeof(RaidIOControl));
  171.  
  172.     Sync_SemInitDynamic(&IOControlPtr->mutex, "RAID IOControl Sema");
  173.     IOControlPtr->numIO            = 0;
  174.     IOControlPtr->doneProc        = doneProc;
  175.     IOControlPtr->clientData        = clientData;
  176.     IOControlPtr->status        = SUCCESS;
  177.     IOControlPtr->amountTransferred    = 0;
  178.     IOControlPtr->numFailed        = 0;
  179.     IOControlPtr->failedReqPtr        = (RaidBlockRequest *) NIL;
  180.  
  181.     return IOControlPtr;
  182. }
  183.  
  184.  
  185. /*
  186.  *----------------------------------------------------------------------
  187.  *
  188.  * Raid_FreeIOControl --
  189.  *
  190.  *    Free RaidIOControl.
  191.  *
  192.  * Results:
  193.  *    None.
  194.  *
  195.  * Side effects:
  196.  *    None.
  197.  *
  198.  *----------------------------------------------------------------------
  199.  */
  200.  
  201. void
  202. Raid_FreeIOControl(IOControlPtr)
  203.     RaidIOControl    *IOControlPtr;
  204. {
  205.     Sync_LockClear(&IOControlPtr->mutex);
  206.     Free((char *) IOControlPtr);
  207. }
  208.  
  209.  
  210. /*
  211.  *----------------------------------------------------------------------
  212.  *
  213.  * MakeRaidRequestControl --
  214.  *
  215.  *    Allocate and initialize RaidRequestControl.
  216.  *
  217.  * Results:
  218.  *    None.
  219.  *
  220.  * Side effects:
  221.  *    None.
  222.  *
  223.  *----------------------------------------------------------------------
  224.  */
  225.  
  226. RaidRequestControl *
  227. Raid_MakeRequestControl(raidPtr)
  228.     Raid    *raidPtr;
  229. {
  230.     RaidRequestControl    *reqControlPtr;
  231.  
  232.     reqControlPtr = (RaidRequestControl *) Malloc(sizeof(RaidRequestControl));
  233.     reqControlPtr->reqPtr = (RaidBlockRequest *)
  234.             Malloc((unsigned) (raidPtr->numCol+4) * sizeof(RaidBlockRequest));
  235.     reqControlPtr->numReq = 0;
  236.     reqControlPtr->numFailed = 0;
  237.     reqControlPtr->failedReqPtr = (RaidBlockRequest *) NIL;
  238.  
  239.     return reqControlPtr;
  240. }
  241.  
  242.  
  243. /*
  244.  *----------------------------------------------------------------------
  245.  *
  246.  * Raid_FreeRequestControl --
  247.  *
  248.  *    Free RaidRequestControl.
  249.  *
  250.  * Results:
  251.  *    None.
  252.  *
  253.  * Side effects:
  254.  *    None.
  255.  *
  256.  *----------------------------------------------------------------------
  257.  */
  258.  
  259. void
  260. Raid_FreeRequestControl(reqControlPtr)
  261.     RaidRequestControl    *reqControlPtr;
  262. {
  263.     Free((char *) reqControlPtr->reqPtr);
  264.     Free((char *) reqControlPtr);
  265. }
  266.  
  267.  
  268. /*
  269.  *----------------------------------------------------------------------
  270.  *
  271.  * MakeRaidStripeIOControl --
  272.  *
  273.  *    Allocate and initialize RaidStripeIOControl.
  274.  *
  275.  * Results:
  276.  *    None.
  277.  *
  278.  * Side effects:
  279.  *    None.
  280.  *
  281.  *----------------------------------------------------------------------
  282.  */
  283.  
  284. RaidStripeIOControl *
  285. Raid_MakeStripeIOControl(raidPtr, operation, firstSector, nthSector, buffer,
  286.     doneProc, clientData, ctrlData)
  287.     Raid                *raidPtr;
  288.     int             operation;
  289.     unsigned             firstSector;
  290.     unsigned             nthSector;
  291.     Address              buffer;
  292.     void               (*doneProc)();
  293.     ClientData           clientData;
  294.     int                  ctrlData;
  295. {
  296.     RaidStripeIOControl    *stripeIOControlPtr;
  297.     stripeIOControlPtr = (RaidStripeIOControl *)
  298.                  Malloc(sizeof(RaidStripeIOControl));
  299.  
  300.     stripeIOControlPtr->raidPtr       = raidPtr;
  301.     stripeIOControlPtr->operation     = operation;
  302.     stripeIOControlPtr->firstSector   = firstSector;
  303.     stripeIOControlPtr->nthSector     = nthSector;
  304.     stripeIOControlPtr->buffer        = buffer;
  305.     stripeIOControlPtr->doneProc      = doneProc;
  306.     stripeIOControlPtr->clientData    = clientData;
  307.     stripeIOControlPtr->recoverProc   = (void (*)()) NIL;
  308.     stripeIOControlPtr->ctrlData      = ctrlData;
  309.     stripeIOControlPtr->reqControlPtr = Raid_MakeRequestControl(raidPtr);
  310.     stripeIOControlPtr->parityBuf     =
  311. #ifdef NODATA
  312.         (char *) NIL;
  313. #else
  314.             Malloc((unsigned) raidPtr->bytesPerStripeUnit);
  315. #endif
  316.     stripeIOControlPtr->readBuf       =
  317. #ifdef NODATA
  318.         (char *) NIL;
  319. #else
  320.         Malloc((unsigned) raidPtr->dataBytesPerStripe);
  321. #endif
  322.     stripeIOControlPtr->rangeOff      = 0;
  323.     stripeIOControlPtr->rangeLen      = 0;
  324.  
  325.     return stripeIOControlPtr;
  326. }
  327.  
  328.  
  329. /*
  330.  *----------------------------------------------------------------------
  331.  *
  332.  * Raid_FreeStripeIOControl --
  333.  *
  334.  *    Free RaidStripeIOControl.
  335.  *
  336.  * Results:
  337.  *    None.
  338.  *
  339.  * Side effects:
  340.  *    None.
  341.  *
  342.  *----------------------------------------------------------------------
  343.  */
  344.  
  345. void
  346. Raid_FreeStripeIOControl(stripeIOControlPtr)
  347.     RaidStripeIOControl    *stripeIOControlPtr;
  348. {
  349.     Raid_FreeRequestControl(stripeIOControlPtr->reqControlPtr);
  350. #ifndef NODATA
  351.     Free((char *) stripeIOControlPtr->parityBuf);
  352.     Free((char *) stripeIOControlPtr->readBuf);
  353. #endif
  354.     Free((char *) stripeIOControlPtr);
  355. }
  356.  
  357.  
  358. /*
  359.  *----------------------------------------------------------------------
  360.  *
  361.  * MakeRaidReconstructionControl --
  362.  *
  363.  *    Allocate and initialize RaidReconstructionControl.
  364.  *
  365.  * Results:
  366.  *    None.
  367.  *
  368.  * Side effects:
  369.  *    None.
  370.  *
  371.  *----------------------------------------------------------------------
  372.  */
  373.  
  374. RaidReconstructionControl *
  375. Raid_MakeReconstructionControl(raidPtr, col, row, diskPtr, doneProc, clientData,
  376.     ctrlData)
  377.     Raid        *raidPtr;
  378.     int         col;
  379.     int         row;
  380.     RaidDisk    *diskPtr;
  381.     void       (*doneProc)();
  382.     ClientData   clientData;
  383.     int         ctrlData;
  384. {
  385.     RaidReconstructionControl *reconstructionControlPtr;
  386.     reconstructionControlPtr = (RaidReconstructionControl *)
  387.         Malloc(sizeof(RaidReconstructionControl));
  388.  
  389.     reconstructionControlPtr->raidPtr       = raidPtr;
  390.     reconstructionControlPtr->col           = col;
  391.     reconstructionControlPtr->row           = row;
  392.     reconstructionControlPtr->diskPtr       = diskPtr;
  393.     reconstructionControlPtr->stripeID      = 0;
  394.     reconstructionControlPtr->numStripe     = 0;
  395.     reconstructionControlPtr->doneProc      = doneProc;
  396.     reconstructionControlPtr->clientData    = clientData;
  397.     reconstructionControlPtr->ctrlData      = ctrlData;
  398.     reconstructionControlPtr->reqControlPtr = Raid_MakeRequestControl(raidPtr);
  399.     reconstructionControlPtr->status        = SUCCESS;
  400.     reconstructionControlPtr->parityBuf     =
  401. #ifdef NODATA
  402.         (char *) NIL;
  403. #else
  404.             Malloc((unsigned) raidPtr->bytesPerStripeUnit);
  405. #endif
  406.     reconstructionControlPtr->readBuf       =
  407. #ifdef NODATA
  408.         (char *) NIL;
  409. #else
  410.         Malloc((unsigned) raidPtr->dataBytesPerStripe);
  411. #endif
  412.     return reconstructionControlPtr;
  413. }
  414.  
  415.  
  416. /*
  417.  *----------------------------------------------------------------------
  418.  *
  419.  * Raid_FreeReconstructionControl --
  420.  *
  421.  *    Free RaidReconstructionControl.
  422.  *
  423.  * Results:
  424.  *    None.
  425.  *
  426.  * Side effects:
  427.  *    None.
  428.  *
  429.  *----------------------------------------------------------------------
  430.  */
  431.  
  432. void
  433. Raid_FreeReconstructionControl(reconstructionControlPtr)
  434.     RaidReconstructionControl *reconstructionControlPtr;
  435. {
  436.     Raid_FreeRequestControl(reconstructionControlPtr->reqControlPtr);
  437. #ifndef NODATA
  438.     Free((char *) reconstructionControlPtr->parityBuf);
  439.     Free((char *) reconstructionControlPtr->readBuf);
  440. #endif
  441.     Free((char *) reconstructionControlPtr);
  442. }
  443.  
  444.  
  445. /*
  446.  *----------------------------------------------------------------------
  447.  *
  448.  * Raid_RangeRestrict --
  449.  *
  450.  *    Restricts start and len so that they lie within rangeOffset and
  451.  *    rangeLen.  Note that start is restricted modulo the fieldLen.
  452.  *
  453.  * Results:
  454.  *    The restricted values of start and len (newStart, newLen).
  455.  *
  456.  * Side effects:
  457.  *    None.
  458.  *
  459.  *----------------------------------------------------------------------
  460.  */
  461.  
  462. void
  463. Raid_RangeRestrict(start, len, rangeOffset, rangeLen, fieldLen, newStart, newLen)
  464.     int         start, len;
  465.     int         rangeOffset, rangeLen;
  466.     int         fieldLen;
  467.     int        *newStart, *newLen;
  468. {
  469.     int         startBase, startOffset;
  470.     int         newStartOffset;
  471.  
  472.     startOffset = start % fieldLen;
  473.     startBase   = (start / fieldLen) * fieldLen;
  474.     newStartOffset = MAX(startOffset, rangeOffset);
  475.     *newStart = startBase + newStartOffset;
  476.     *newLen = MIN(startOffset + len, rangeOffset + rangeLen) - newStartOffset;
  477. }
  478.  
  479.  
  480. /*
  481.  *----------------------------------------------------------------------
  482.  *
  483.  * Raid_XorRangeRequests --
  484.  *
  485.  *    Xor's the contents of the buffers of the requests in *reqControlPtr 
  486.  *    restricted by rangeOffset and rangeLen and place the result in 
  487.  *    *destBuf.
  488.  *
  489.  * Results:
  490.  *      *destBuf.
  491.  *
  492.  * Side effects:
  493.  *    None.
  494.  *
  495.  *----------------------------------------------------------------------
  496.  */
  497.  
  498. void
  499. Raid_XorRangeRequests(reqControlPtr, raidPtr, destBuf, rangeOffset, rangeLen)
  500.     RaidRequestControl    *reqControlPtr;
  501.     Raid        *raidPtr;
  502.     char        *destBuf;   
  503.     int             rangeOffset;
  504.     int             rangeLen;
  505. {
  506.     RaidBlockRequest    *reqPtr;
  507.     int             rangeStartAddress;
  508.     int             newRangeLen;
  509.     int             i;
  510.  
  511.     rangeOffset = StripeUnitOffset(raidPtr, rangeOffset);
  512.     for (i = 0; i < reqControlPtr->numReq; i++) {
  513.     reqPtr = &reqControlPtr->reqPtr[i];
  514.     if (reqPtr->state == REQ_READY || reqPtr->state == REQ_COMPLETED ) {
  515.         Raid_RangeRestrict((int) reqPtr->devReq.startAddress,
  516.             reqPtr->devReq.bufferLen,
  517.             rangeOffset, rangeLen, raidPtr->bytesPerStripeUnit,
  518.             &rangeStartAddress, &newRangeLen);
  519.             Xor2(newRangeLen, reqPtr->devReq.buffer +
  520.                     (rangeStartAddress - reqPtr->devReq.startAddress),
  521.             destBuf + StripeUnitOffset(raidPtr,
  522.                 rangeStartAddress)-rangeOffset);
  523.     }
  524.     }
  525. }
  526.  
  527.  
  528. /*
  529.  *----------------------------------------------------------------------
  530.  *
  531.  * Raid_AddParityRangeRequest --
  532.  *
  533.  *    Add a RaidBlockRequest for the indicated parity sectors to
  534.  *    reqControlPtr.
  535.  *
  536.  * Results:
  537.  *    Updates reqControlPtr.
  538.  *
  539.  * Side effects:
  540.  *    None.
  541.  *
  542.  *----------------------------------------------------------------------
  543.  */
  544.  
  545. void
  546. Raid_AddParityRangeRequest(reqControlPtr, raidPtr, operation,
  547.     sector, buffer, ctrlData, rangeOffset, rangeLen)
  548.     RaidRequestControl    *reqControlPtr;
  549.     Raid        *raidPtr;
  550.     int             operation;
  551.     unsigned         sector;
  552.     Address         buffer;
  553.     int             ctrlData;
  554.     int             rangeOffset;
  555.     int             rangeLen;
  556. {
  557.     RaidBlockRequest    *reqPtr;
  558.     int             col, row;
  559.     int          numSectorsToTransfer;
  560.     unsigned         diskSector;
  561.  
  562.     rangeOffset = ByteToSector(raidPtr, StripeUnitOffset(raidPtr, rangeOffset));
  563.     rangeLen    = ByteToSector(raidPtr, rangeLen);
  564.  
  565.     reqPtr = &reqControlPtr->reqPtr[reqControlPtr->numReq];
  566.     sector = FirstSectorOfStripeUnit(raidPtr, sector) + rangeOffset;
  567.     numSectorsToTransfer = rangeLen;
  568.  
  569.     /*
  570.      * Map logical Raid sector address to (diskHandlePtr, diskSector).
  571.      */
  572.     Raid_MapParity(raidPtr, sector, &col, &row, &diskSector);
  573.  
  574.     if (numSectorsToTransfer > 0) {
  575.     InitRaidBlockRequest(reqPtr, raidPtr, operation, col, row,
  576.         diskSector, numSectorsToTransfer, buffer, ctrlData);
  577.     if ( IsValid(reqPtr->diskPtr, diskSector, numSectorsToTransfer) ) {
  578.         reqPtr->state = REQ_READY;
  579.     } else {
  580.         reqPtr->state = REQ_INVALID;
  581.         reqControlPtr->numFailed++;
  582.         reqControlPtr->failedReqPtr = reqPtr;
  583.     }
  584.         reqControlPtr->numReq++;
  585.     }
  586.     if (reqControlPtr->numReq >= raidPtr->numCol +4) {
  587.     panic("Error: AddRaidParity: reqControl overrun.\n");
  588.     }
  589. }
  590.  
  591.  
  592. /*
  593.  *----------------------------------------------------------------------
  594.  *
  595.  * Raid_AddDataRangeRequests --
  596.  *
  597.  *    Add RaidBlockRequest's for the indicated data sectors to
  598.  *    reqControlPtr.
  599.  *
  600.  * Results:
  601.  *    Updates reqControlPtr.
  602.  *
  603.  * Side effects:
  604.  *    None.
  605.  *
  606.  *----------------------------------------------------------------------
  607.  */
  608.  
  609. void
  610. Raid_AddDataRangeRequests(reqControlPtr, raidPtr, operation,
  611.         firstSector, nthSector, buffer, ctrlData, rangeOffset, rangeLen)
  612.     RaidRequestControl    *reqControlPtr;
  613.     Raid        *raidPtr;
  614.     int             operation;
  615.     unsigned         firstSector, nthSector;
  616.     Address         buffer;
  617.     int             ctrlData;
  618.     int             rangeOffset;
  619.     int             rangeLen;
  620. {
  621.     RaidBlockRequest    *reqPtr;
  622.     int             col, row;
  623.     int          numSectorsToTransfer;
  624.     int          rangeSectorsToTransfer;
  625.     unsigned          currentSector;
  626.     unsigned         diskSector;
  627.  
  628.     rangeOffset = ByteToSector(raidPtr, StripeUnitOffset(raidPtr, rangeOffset));
  629.     rangeLen    = ByteToSector(raidPtr, rangeLen);
  630.     /*
  631.      * Break up requests into stripe units.
  632.      */
  633.     currentSector = firstSector;
  634.     while ( currentSector < nthSector ) {
  635.     reqPtr = &reqControlPtr->reqPtr[reqControlPtr->numReq];
  636.         numSectorsToTransfer = MIN( raidPtr->sectorsPerStripeUnit -
  637.         currentSector%raidPtr->sectorsPerStripeUnit,
  638.         nthSector - currentSector );
  639.     /*
  640.      * Map logical Raid sector address to (diskHandlePtr, diskSector).
  641.      */
  642.     Raid_MapSector(raidPtr, currentSector, &col, &row, &diskSector);
  643.  
  644.     Raid_RangeRestrict((int) diskSector, numSectorsToTransfer,
  645.         rangeOffset, rangeLen,
  646.         raidPtr->sectorsPerStripeUnit,
  647.         (int *) &(diskSector), &rangeSectorsToTransfer);
  648.  
  649.     if (rangeSectorsToTransfer > 0) {
  650.         InitRaidBlockRequest(reqPtr, raidPtr, operation, col, row,
  651.             diskSector, rangeSectorsToTransfer, buffer, ctrlData);
  652.         if (IsValid(reqPtr->diskPtr, diskSector,rangeSectorsToTransfer)) {
  653.         reqPtr->state = REQ_READY;
  654.         } else {
  655.         reqPtr->state = REQ_INVALID;
  656.         reqControlPtr->numFailed++;
  657.         reqControlPtr->failedReqPtr = reqPtr;
  658.         }
  659.         reqControlPtr->numReq++;
  660.     }
  661.  
  662.         currentSector += numSectorsToTransfer;
  663.     buffer += SectorToByte(raidPtr, numSectorsToTransfer);
  664.     }
  665.     if (reqControlPtr->numReq >= raidPtr->numCol +4) {
  666.     panic("Error: AddRaidData: reqControl overrun.\n");
  667.     }
  668. }
  669.